Hi,昨天說到了 CSS 的使用,今天接續昨天的內容,我們要使用 SCSS 的機制現有的 CSS 架構進行調整,那麼讓我們開始吧
昨天有稍微提到了 CSS 的階層式、偽元素、虛擬類別…等。隨著CSS的不斷進步,可以做到的東西越來越多,也代表 CSS 越來越複雜,維護成本開始增加,這時候出現了許多種維護CSS的手法,所謂的「CSS 預處理器」也是其中之一,今天要提的SCSS,就是一種CSS 預處理器的作法。
為什麼要使用SCSS呢?我們先從一般的CSS 設定來看,一般的 CSS 的設定是以樣式名稱逐項逐項設定的,一個個樣式設定水平擴展,類似下面的樣子
<style>
.formtitle {
font-weight: 700;
}
.err {
color: red;
background-color: pink;
}
.formtitle::before {
color: red;
content: "*";
}
</style>
像上方的基本上是沒有問題的,樣式可以正常運作,但是可以看到 formtitle 和 formtitle::before 的設定是分開的,若是處理CSS的人習慣不好,沒有寫在一起時,我們要找的樣式就可能會散落在檔案的任何一個地方。
再者 CSS 本身是沒有所謂的繼承機制的,若是我要設定3種樣式相同,只是不同色系的按鈕,要嘛是用js在執行時調整顏色,要麻就是像下方程式碼一樣複製貼上不同顏色的3組樣式設定
<style>
.myButton {
background-color:#44c767;
border-radius:28px;
border:1px solid #18ab29;
display:inline-block;
cursor:pointer;
color:#ffffff;
font-family:Arial;
font-size:17px;
padding:16px 31px;
text-decoration:none;
text-shadow:0px 1px 0px #2f6627;
}
.myButton:hover {
background-color:#5cbf2a;
}
.myButton:active {
position:relative;
top:1px;
}
.myButton2 {
background-color:#7892c2;
border-radius:28px;
border:1px solid #4e6096;
display:inline-block;
cursor:pointer;
color:#ffffff;
font-family:Arial;
font-size:17px;
padding:16px 31px;
text-decoration:none;
text-shadow:0px 1px 0px #283966;
}
.myButton2:hover {
background-color:#476e9e;
}
.myButton2:active {
position:relative;
top:1px;
}
.myButton3 {
background-color:#ededed;
border-radius:28px;
border:1px solid #d6bcd6;
display:inline-block;
cursor:pointer;
color:#3a8a9e;
font-family:Arial;
font-size:17px;
padding:16px 31px;
text-decoration:none;
text-shadow:0px 1px 0px #e1e2ed;
}
.myButton3:hover {
background-color:#bab1ba;
}
.myButton3:active {
position:relative;
top:1px;
}
</style>
可以看得出來CSS變得又臭又長,而且大多數的內容都一樣。像這個時候,我們就可以採用SCSS 來解決這種問題了。
SCSS 的使用,其實可以說是將 CSS 以SCSS 的規則先寫好後,再進行編譯的動作,就像寫 java時需要從 java 編譯成 class 一樣,使用 SCSS 時,也是要將 scss 編譯成為 css。通常的作法是下載 scss 套件,需要編譯時下指令處理,但是秉持著能夠躺著絕對不坐著的懶人精神,我們要在 vscode 的建置自動編譯的環境,操作方法如下
要將 CSS 轉換成 SCSS 其實很簡單,即便是開發到一半的專案也不困難,執行過程中其實還有一點重構的味道,一般的我的做法,會先現有的 CSS 全部都複製到新增的 SCSS 檔中,然後就可以開始整理CSS了
例如像下方的情況,偽元素、虛擬類別
.formtitle input {
border: 1px solid blue;
background-color: #F5F178;
}
.formtitle {
font-weight: 700;
}
.formtitle::before {
color: red;
content: "*";
}
.showLock {
border: 3px solid #bfbfbf;
text-align: left;
padding: 15px;
padding-top: 20px;
margin: 5px;
border-radius: 50px;
cursor: pointer
}
.showLock:hover {
background-color: rgb(207, 207, 207);
border: 5px solid #bfbfbf;
}
.require input {
border: 1px solid blue;
background-color: #F5F178;
}
我們就可以改寫成SCSS 的階層式架構
.formtitle {
font-weight: 700;
&::before {
color: red;
content: "*";
}
}
.showLock {
border: 3px solid #bfbfbf;
text-align: left;
padding: 15px;
padding-top: 20px;
margin: 5px;
border-radius: 50px;
cursor: pointer;
&:hover {
background-color: rgb(207, 207, 207);
border: 5px solid #bfbfbf;
}
}
.require {
input {
border: 1px solid blue;
background-color: #F5F178;
}
}
若是要設定自己下載的樣式,就寫成階層式的寫法,使用上非常的直觀,若是要設定自己本身要用到的偽元素、虛擬類別…等,可以使用「&」表示是自己同一層的設定值,所以「&::before」指的就是「.formtitle::before」,「&:hover」則是「.showLock:hover」,可以明顯看得出來,屬於自己的東西就可以寫在一起,增加管理的方便性
另外 SCSS 有支援繼承與混合2種做法,可以處理樣式內容大同小異之問題,例如下面這個狀況
.myButton {
background-color:#44c767;
border-radius:28px;
border:1px solid #18ab29;
display:inline-block;
cursor:pointer;
color:#ffffff;
font-family:Arial;
font-size:17px;
padding:16px 31px;
text-decoration:none;
text-shadow:0px 1px 0px #2f6627;
}
.myButton:hover {
background-color:#5cbf2a;
}
.myButton:active {
position:relative;
top:1px;
}
.myButton2 {
background-color:#7892c2;
border-radius:28px;
border:1px solid #4e6096;
display:inline-block;
cursor:pointer;
color:#ffffff;
font-family:Arial;
font-size:17px;
padding:16px 31px;
text-decoration:none;
text-shadow:0px 1px 0px #283966;
}
.myButton2:hover {
background-color:#476e9e;
}
.myButton2:active {
position:relative;
top:1px;
}
.myButton3 {
background-color:#ededed;
border-radius:28px;
border:1px solid #d6bcd6;
display:inline-block;
cursor:pointer;
color:#3a8a9e;
font-family:Arial;
font-size:17px;
padding:16px 31px;
text-decoration:none;
text-shadow:0px 1px 0px #e1e2ed;
}
.myButton3:hover {
background-color:#bab1ba;
}
.myButton3:active {
position:relative;
top:1px;
}
我們可以改成
//基本按鈕
%basebtn {
border-radius:28px;
display:inline-block;
cursor:pointer;
color:#ffffff;
font-family:Arial;
font-size:17px;
padding:16px 31px;
text-decoration:none;
&:active {
position:relative;
top:1px;
}
}
.myButton {
@extend %basebtn;
background-color:#44c767;
border:1px solid #18ab29;
text-shadow:0px 1px 0px #2f6627;
&:hover {
background-color:#5cbf2a;
}
}
.myButton2 {
@extend %basebtn;
background-color:#7892c2;
border:1px solid #4e6096;
text-shadow:0px 1px 0px #283966;
&:hover {
background-color:#476e9e;
}
}
.myButton3 {
@extend %basebtn;
background-color:#ededed;
border:1px solid #d6bcd6;
color:#3a8a9e;
text-shadow:0px 1px 0px #e1e2ed;
&:hover {
background-color:#bab1ba;
}
}
和寫物件導向語言一樣,將重複的東西放到一個基本按鈕樣式上,之後所有的按鈕利用 @extend 的方法,繼承基本按鈕,並設定不同地方的樣式(例如背景色、框線…等),若是有共通的地方要調整,只要調整基本按鈕,所有繼承自基本按鈕的子子孫孫按鈕都會一起改掉,在管理上是很方便的機制。
另外也可以用 @mixin 達到相同的效果,@mixin 和 @extend 兩者的差異是在最終產出之CSS內容上,@mixin 意指混合,所以最終的 CSS 會向是我們在複製貼上一樣,會有不少重複的程式碼,但是
@extend 不會有這種情形,若是在意產出 CSS 的大小,可以統一使用 @extend
SCSS 可以設定變數,變數以 「$」開頭,設定變數的好處是可以集中管理,例如下面的例子
$brcolor: green;
$brline: 1px;
.tr {
border-top: $brline solid $brcolor;
}
.dr {
border-left: $brline solid $brcolor;
border-right: $brline solid $brcolor;
}
.title {
background-color: rgb(152, 253, 152);
border-bottom: $brline solid $brcolor;
}
我們設定了 $brcolor 與 $brline 的2個變數,哪一天老闆要換顏色時,我們只要調整變數內容就行了,整個網站都一起換掉
我們將原先散茖在各個 ejs 的樣式,集結起來,並改成 SCSS 的內容,改寫過程中,其實也等於重構了 CSS 的內容了,最終的整理成果如下,和原本四處散茖的結果比起來,可讀性與易維護性都大增
$brcolor: green;
$brline: 1px;
.tr {
border-top: $brline solid $brcolor;
}
.dr {
border-left: $brline solid $brcolor;
border-right: $brline solid $brcolor;
}
.title {
background-color: rgb(152, 253, 152);
border-bottom: $brline solid $brcolor;
}
.info {
background-color: rgb(202, 255, 202);
border-bottom: $brline solid $brcolor;
}
.txtr {
text-align: right;
}
.inpcc {
background-color: lightyellow;
color: orange;
border-bottom: $brline solid $brcolor;
}
.tc {
text-align: center;
}
.err {
color: red;
background-color: pink;
}
.showLock {
border: 3px solid #bfbfbf;
text-align: left;
padding: 15px;
padding-top: 20px;
margin: 5px;
border-radius: 50px;
cursor: pointer;
&:hover {
background-color: rgb(207, 207, 207);
border: 5px solid #bfbfbf;
}
}
.require {
input {
border: 1px solid blue;
background-color: #F5F178;
}
}
.formtitle {
font-weight: 700;
&::before {
color: red;
content: "*";
}
}
%basebtn {
border-radius:28px;
display:inline-block;
cursor:pointer;
color:#ffffff;
font-family:Arial;
font-size:17px;
padding:16px 31px;
text-decoration:none;
&:active {
position:relative;
top:1px;
}
}
.myButton {
@extend %basebtn;
background-color:#44c767;
border:1px solid #18ab29;
text-shadow:0px 1px 0px #2f6627;
&:hover {
background-color:#5cbf2a;
}
}
.myButton2 {
@extend %basebtn;
background-color:#7892c2;
border:1px solid #4e6096;
text-shadow:0px 1px 0px #283966;
&:hover {
background-color:#476e9e;
}
}
.myButton3 {
@extend %basebtn;
background-color:#ededed;
border:1px solid #d6bcd6;
color:#3a8a9e;
text-shadow:0px 1px 0px #e1e2ed;
&:hover {
background-color:#bab1ba;
}
}
SCSS 很好用,而且還有很多其他的功能,例如 import 機制、運算機制…等,就留給各位自己去發現啦,明天就是最後一天了,一個月過得真快啊,那麼我們明天見啦